gtk: Check implicit grab status before sending crossing events
authorCarlos Garnacho <carlosg@gnome.org>
Wed, 24 May 2017 23:57:22 +0000 (01:57 +0200)
committerCarlos Garnacho <carlosg@gnome.org>
Thu, 25 May 2017 14:25:59 +0000 (16:25 +0200)
As we now refrain from sending the crossing events if there's an
implicit grab, those events must be sent on button release when
the implicit grab is broken.

gtk/gtkmain.c
gtk/gtkwindow.c
gtk/gtkwindowprivate.h

index c484b49f24d9317096d39fcae79dd81343f80890..c5f601d843ca6f07607ff32416385bcefd6adcd8 100644 (file)
@@ -1508,8 +1508,12 @@ handle_pointing_event (GdkEvent *event)
 
       if (event->type == GDK_MOTION_NOTIFY || event->type == GDK_ENTER_NOTIFY)
         {
-          gtk_synthesize_crossing_events (toplevel, old_target, target,
-                                          event, GDK_CROSSING_NORMAL);
+          if (!gtk_window_lookup_pointer_focus_implicit_grab (toplevel, device,
+                                                              sequence))
+            {
+              gtk_synthesize_crossing_events (toplevel, old_target, target,
+                                              event, GDK_CROSSING_NORMAL);
+            }
 
           gtk_window_maybe_update_cursor (toplevel, NULL, device);
         }
@@ -1532,7 +1536,13 @@ handle_pointing_event (GdkEvent *event)
                                          target : NULL);
 
       if (event->type == GDK_BUTTON_RELEASE)
-        gtk_window_maybe_update_cursor (toplevel, NULL, device);
+        {
+          old_target = target;
+          target = _gtk_toplevel_pick (toplevel, x, y, NULL, NULL);
+          gtk_synthesize_crossing_events (toplevel, old_target, target, event,
+                                          GDK_CROSSING_UNGRAB);
+          gtk_window_maybe_update_cursor (toplevel, NULL, device);
+        }
       break;
     case GDK_SCROLL:
     case GDK_TOUCHPAD_PINCH:
index 1f7e3d84d3d0faaed87d8ed9895e8569da27e6ea..03046731cb13b7a5b70117c2c795a6bdef59129a 100644 (file)
@@ -11327,6 +11327,17 @@ gtk_window_lookup_effective_pointer_focus_widget (GtkWindow        *window,
   return focus ? gtk_pointer_focus_get_effective_target (focus) : NULL;
 }
 
+GtkWidget *
+gtk_window_lookup_pointer_focus_implicit_grab (GtkWindow        *window,
+                                               GdkDevice        *device,
+                                               GdkEventSequence *sequence)
+{
+  GtkPointerFocus *focus;
+
+  focus = gtk_window_lookup_pointer_focus (window, device, sequence);
+  return focus ? gtk_pointer_focus_get_implicit_grab (focus) : NULL;
+}
+
 void
 gtk_window_update_pointer_focus (GtkWindow        *window,
                                  GdkDevice        *device,
index 1d97de7a1a3828e7b6d22189199cc231dc172c85..94b5aee9588ff50507f67d10ad044b83299e2179 100644 (file)
@@ -146,6 +146,9 @@ GtkWidget *      gtk_window_lookup_pointer_focus_widget (GtkWindow        *windo
 GtkWidget *      gtk_window_lookup_effective_pointer_focus_widget (GtkWindow        *window,
                                                                    GdkDevice        *device,
                                                                    GdkEventSequence *sequence);
+GtkWidget *      gtk_window_lookup_pointer_focus_implicit_grab (GtkWindow        *window,
+                                                                GdkDevice        *device,
+                                                                GdkEventSequence *sequence);
 
 void             gtk_window_update_pointer_focus (GtkWindow        *window,
                                                   GdkDevice        *device,